package com.cardone.persistent.builder;

import com.google.common.collect.*;
import lombok.*;
import lombok.experimental.*;
import org.apache.commons.lang3.*;
import org.springframework.data.annotation.*;
import org.springframework.util.*;

import java.lang.annotation.*;
import java.util.*;

/**
 * 对象参数
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Accessors(chain = true)
public class ModelArgs implements java.io.Serializable {
    /**
     * 序列号
     */
    private static final long serialVersionUID = -6258631484971104514L;

    /**
     * 类型
     */
    private Class<?> c;

    /**
     * 忽略Annotation类型集合
     */
    private List<Class<? extends Annotation>> ignoreAnnotationClassList;

    /**
     * 忽略属性数组
     */
    private String[] ignoreProperties;

    private Boolean isSimple;

    /**
     * 键基本名称
     */
    private String[] keyBases;

    /**
     * 键前缀名称
     */
    private String keyPrefix;

    /**
     * 键后缀名称
     */
    private String keySuffix;

    /**
     * 键值映射
     */
    private Map<String, Object> kvMap;

    /**
     * 对象
     */
    private Object o;

    /**
     * 跳过空值
     */
    private Boolean skipNullValue;

    /**
     * 使用Annotation类型集合
     */
    private List<Class<? extends Annotation>> useAnnotationClassList;

    /**
     * 使用属性数组
     */
    private String[] useProperties;

    /**
     * 值
     */
    private Object value;

    /**
     * 对象参数
     *
     * @param c 类型
     */
    public ModelArgs(final Class<?> c) {
        this.c = c;
    }

    /**
     * 对象参数
     *
     * @param o 对象
     * @param c 类型
     */
    public ModelArgs(final Object o, final Class<?> c) {
        this.o = o;
        this.c = c;
    }

    /**
     * 对象参数
     *
     * @param o             对象
     * @param useProperties 使用属性数组
     */
    public ModelArgs(final Object o, final String... useProperties) {
        this.o = o;
        this.useProperties = useProperties;
    }

    /**
     * 对象参数
     *
     * @param kvMap         对象
     * @param useProperties 使用属性数组
     */
    public ModelArgs(final Map<String, Object> kvMap, final String... useProperties) {
        this.kvMap = kvMap;
        this.useProperties = useProperties;
    }

    /**
     * 对象参数
     *
     * @param keyPrefix 键前缀名称
     */
    public ModelArgs(final String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    /**
     * 对象参数
     *
     * @param keyPrefix     键前缀名称
     * @param o             对象
     * @param useProperties 使用属性数组
     */
    public ModelArgs(final String keyPrefix, final Object o, final String... useProperties) {
        this.keyPrefix = keyPrefix;
        this.o = o;
        this.useProperties = useProperties;
    }

    /**
     * 对象参数
     *
     * @param keyPrefix     键前缀名称
     * @param kvMap         对象
     * @param useProperties 使用属性数组
     */
    public ModelArgs(final String keyPrefix, final Map<String, Object> kvMap, final String... useProperties) {
        this.keyPrefix = keyPrefix;
        this.kvMap = kvMap;
        this.useProperties = useProperties;
    }

    /**
     * 添加
     *
     * @param ignoreAnnotationClass 忽略Annotation
     * @return 对象参数
     */
    public ModelArgs addIgnoreAnnotationClassList(final Class<? extends Annotation> ignoreAnnotationClass) {
        if (CollectionUtils.isEmpty(this.ignoreAnnotationClassList)) {
            this.ignoreAnnotationClassList = Lists.newArrayList();

            this.ignoreAnnotationClassList.add(Transient.class);
        }

        if (!this.ignoreAnnotationClassList.contains(ignoreAnnotationClass)) {
            this.ignoreAnnotationClassList.add(ignoreAnnotationClass);
        }

        return this;
    }

    /**
     * 添加
     *
     * @param useAnnotationClass 使用Annotation
     * @return 对象参数
     */
    public ModelArgs addUseAnnotationClassList(final Class<? extends Annotation> useAnnotationClass) {
        if (CollectionUtils.isEmpty(this.useAnnotationClassList)) {
            this.useAnnotationClassList = Lists.newArrayList();
        }

        this.useAnnotationClassList.add(useAnnotationClass);

        return this;
    }

    /**
     * 获取
     *
     * @return 忽略Annotation类型集合
     */
    public List<Class<? extends Annotation>> getIgnoreAnnotationClassList() {
        if (CollectionUtils.isEmpty(this.ignoreAnnotationClassList)) {
            this.ignoreAnnotationClassList = Lists.newArrayList();

            this.ignoreAnnotationClassList.add(Transient.class);
        }

        return this.ignoreAnnotationClassList;
    }

    /**
     * 获取
     *
     * @return 忽略属性数组
     */
    public String[] getIgnoreProperties() {
        if (ArrayUtils.isEmpty(this.ignoreProperties)) {
            this.ignoreProperties = new String[]{Model.Keys.serialVersionUID.stringValue()};
        }

        return this.ignoreProperties;
    }

    /**
     * 设置：键值对
     *
     * @param k 键
     * @param v 值
     * @return 对象参数
     */
    public ModelArgs putKvMap(final String k, final Object v) {
        if (CollectionUtils.isEmpty(this.kvMap)) {
            this.kvMap = Maps.newHashMap();
        }

        this.kvMap.put(k, v);

        return this;
    }
}
